using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using Wolfpack.Contrib.BuildAnalytics.Publishers;
using Wolfpack.Core;
using Wolfpack.Core.Configuration;
using Wolfpack.Core.Interfaces.Entities;

namespace Wolfpack.Contrib.BuildAnalytics.Parsers.StoryQ
{
    public class StoryQXmlReportParserConfigurationDiscovery : PluginDiscoveryBase<StoryQXmlReportParserConfig, StoryQXmlReportParser>
    {
        protected override StoryQXmlReportParserConfig GetConfiguration()
        {
            return new StoryQXmlReportParserConfig
            {
                Enabled = true,
                FriendlyId = "CHANGEME!",
                MatchBuildResult = true,
                TargetHealthCheckName = "The FriendlyId of the check that triggers this parser",
                ReportFileTemplate = "report file path, supports {buildid} token",
                ZipFileTemplate = "Report zip filepath (or blank)"
            };
        }

        protected override void Configure(ConfigurationEntry entry)
        {
            entry.Name = "StoryQXmlReportParser";
            entry.Description = "When triggered (usually by a successful Build Notification check) this plugin will" +
                                "parse a Xml StoryQ report and create notifications for the test statistics";
            entry.Tags.AddIfMissing(SpecialTags.PUBLISHER, "BuildAnalytics", "StoryQ");
        }
        
    }

    public class StoryQXmlReportParser : BuildNotificationPublisherBase<StoryQXmlReportParserConfig>
    {
        public const string STORY_Q_REPORT = "StoryQ";

        public StoryQXmlReportParser(StoryQXmlReportParserConfig config)
            : base(config, config.TargetHealthCheckName)
        {
        }

        protected override void Publish(NotificationEvent notification)
        {
            if (string.IsNullOrWhiteSpace(Config.ZipFileTemplate) &&
                string.IsNullOrWhiteSpace(Config.ReportFileTemplate))
                return;

            string reportContent;
            if (!GetContent(notification, "StoryQ.xml", out reportContent))
                return;

            // finally parse the content for the counts
            Logger.Debug("\tExtracting stats from StoryQ report from build '{0}'...", 
                notification.Properties[NotificationProperties.BuildId]);

            var xdoc = XDocument.Parse(reportContent);
            var resultSummary =
                (from results in xdoc.XPathSelectElements("/StoryQRun/Project/Namespace/Class/Method/Story/Result")
                 group results by results.Attribute("Type").Value
                 into resultGroups
                 select new {Result = resultGroups.Key, Count = resultGroups.Count()}).ToList();

            resultSummary.ForEach(rs => PublishStat(notification, STORY_Q_REPORT, rs.Count, rs.Result));
        }
    }
}